﻿/**
 * 辅助函数，用于确定是否系统唯一
 * 
 * @file Only.h
 * @author Song
 * @date 2011-9-24
 */

#pragma once

#include "Config.h"

namespace helpers {

#if defined(WINDOWS_PLATFORM)

	bool windows_system_only(const char_t* name)
	{
		static HANDLE _global_mutex = NULL;
		if (_global_mutex != NULL) {
			return true;
		}

		_global_mutex = CreateMutex(NULL, TRUE, name);
		if (_global_mutex == NULL) {
			return false;
		}

		if (GetLastError() == ERROR_ALREADY_EXISTS) {
			CloseHandle(_global_mutex);
			_global_mutex = NULL;
			return false;
		}
		return true;
	}
#endif

#if defined(LINUX_GCC_PLATFORM)
	bool linux_system_only(const char_t* name)
	{
		static int fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
		if(fd == -1) {
			perror(T_TEXT("open"));
			return false;
		}
		struct flock lock;
		lock.l_type = F_WRLCK;
		lock.l_start = 0;
		lock.l_whence = SEEK_SET;
		lock.l_len = 0;

		if(fcntl(fd, F_SETLK, &lock) < 0) {
			if (errno == EACCES || errno == EAGAIN)
				return false;
		}
		return true;
	}

#endif

	bool system_only(const char_t* name)
	{
#if defined(WINDOWS_PLATFORM)
		return windows_system_only(name);
#else
		return linux_system_only(name);
#endif
	}
}
